library world;

uses Common, CoreI, lists, SoundSystemI, InputI, WorldI, VectorGeometry, GameObjects, sdl, ScriptEngineI,
LuaBindings, ResourceManagerI, ObjectsHelper;
var PluginInfo:PPluginInfo;
SoundSystem:ISoundSystem;
SoundGeometry:ISoundGeometry;
Reverb:IReverb;

                Function WorldGameEventHandler(event:TSDL_Event):boolean; cdecl;
var PWalk:PList;
begin
result:=true;
                PWalk:=Objects;
case event.type_ of
EVENT_GameAction: begin
result:=false;
                while PWalk<>nil do begin
                if PWalk^.Data = PGameEvent(Event.user.data1)^.obj then begin
                TBasicObject(PGameEvent(event.user.data1)^.obj).ProcessEvent(event);
                break;
                end;
PWalk:=PWalk^.Next;
end;
dispose(PGameEvent(event.user.data1));
end;
EVENT_InputAction: begin
if world_GameObjectExists(PInputAction(event.user.data1)^.data1) then
TBasicObject(PInputAction(event.user.data1)^.data1).ProcessEvent(event);
end;
end;
                end;

                procedure World_Init(const size:single; AmbientReverb:PChar; gravity:TVector3F); cdecl;
begin
SoundGeometry^.SetGeometryWorldSize(size);
reverb^.SetAmbientReverb(AmbientReverb);
Core_RegisterEventHandler(Event_MainLoop, World_UpdateDynamicObjects);
end;

Procedure World_Release(ReleaseUnmanaged:boolean=false); cdecl;
var PWalk,PNext:PList;
begin
                PWalk:=Objects;
                while PWalk<> nil do begin
                PNext:=PWalk^.Next;
if (TBasicObject(PWalk^.Data).flags and GF_Unmanaged <> gf_unmanaged) or (ReleaseUnmanaged = true) then begin
TBasicObject(PWalk^.Data).Free;
                list_removenode(Objects, PWalk);
                                end;
PWalk := PNext;
                end;
                Core_UnregisterEventHandler(World_UpdateDynamicObjects);
                end;

Procedure Init; cdecl;
begin
SoundGeometry:=Core_RequirePlugin(SoundSystemI.SoundGeometryGUID);
Reverb:=Core_RequirePlugin(soundsystemi.ReverbGUID);
LuaBindings.world := PluginInfo^.InterfaceStruct;
GameObjects.world := PluginInfo^.InterfaceStruct;
RegisterLuaBindings;
GameObj_RequireNeededPlugins;
if paramcount()>0 then
IResourceManager(Core_RequirePlugin(ResourceManagerI.ResourceManagerGUID))^.loadPackage(PChar(paramstr(1))) else
IResourceManager(Core_RequirePlugin(ResourceManagerI.ResourceManagerGUID))^.loadPackage(PChar('game.xml'));
IScriptEngine(Core_RequirePlugin(ScriptEngineI.ScriptEngineGUID))^.ExecResource('startup');
Core_RegisterEventHandler(Event_GAMEACTION, WorldGameEventHandler);
Core_RegisterEventHandler(Event_INPUTACTION, WorldGameEventHandler);
                         end;

procedure Free; cdecl;
begin
Core_UnregisterEventHandler(WorldGameEventHandler);
dispose(PluginInfo);
                                                                                       SoundSystem:=nil;
end;

procedure Plugin_GetInfo(var info:PPluginInfo; var length:cardinal); cdecl;
begin
new(PluginInfo);
Length:=1;
info:=PluginInfo;
FillChar(Info^, sizeof(TPluginInfo), 0);
info^.GUID := WorldGUID;
info^.Name := 'World Manager';
info^.Init := Init;
info^.free := free;
new(IWorld(info^.InterfaceStruct));
IWorld(info^.InterfaceStruct)^.Init := World_Init;
IWorld(info^.InterfaceStruct)^.PushGameEvent := World_PushGameEvent;
IWorld(info^.InterfaceStruct)^.Release := World_Release;
end;

             exports Plugin_GetInfo;
begin
end.
